package co.fitstart.weapp.api.dao;

import java.util.Date;
import java.util.List;

import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.persistence.annotation.Execute;
import com.demo2do.core.persistence.annotation.Limit;
import com.demo2do.core.persistence.annotation.Query;
import com.demo2do.core.persistence.annotation.Variable;

import co.fitstart.entity.course.ResultReport;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.round.Goal;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.courseware.CoursewareTag;
import co.fitstart.entity.courseware.assessment.BasicData;
import co.fitstart.entity.courseware.assessment.PostureJoint;
import co.fitstart.entity.courseware.assessment.StudentAssessment;
import co.fitstart.entity.courseware.assessment.StudentHabit;
import co.fitstart.entity.courseware.dietary.Dietary;
import co.fitstart.entity.courseware.exercise.Exercise;
import co.fitstart.entity.courseware.exercise.PlannedSchedule;
import co.fitstart.entity.courseware.fitnessgroup.BatchCourseware;
import co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType;
import co.fitstart.entity.courseware.fitnessgroup.Courseware;
import co.fitstart.entity.courseware.fitnessgroup.CoursewareEditStatus;
import co.fitstart.entity.courseware.fitnessgroup.CoursewareMovementType;
import co.fitstart.entity.courseware.fitnessgroup.DailyCourseware;
import co.fitstart.entity.user.basic.BodyDataTarget;

/**
 * 
 * @author haiyan_xiao
 *
 */
@Dao("hibernate")
public interface CoursewareDao {

    /**
     * 
     * @param courseRound
     * @param scheduleStatuss
     * @param occurDate
     * @param occurHour
     * @return
     */
    @Query("SELECT COUNT(*) FROM CourseSchedule WHERE disabled=false AND courseRound=:courseRound AND scheduleStatus IN (:scheduleStatuss) AND (occurDate<:occurDate OR (occurDate=:occurDate AND occurHour<=:occurHour))")
    public int count(@Variable("courseRound") CourseRound courseRound, @Variable("scheduleStatuss") List<ScheduleStatus> scheduleStatuss, @Variable("occurDate") Date occurDate, @Variable("occurHour") String occurHour);

    /**
     * 
     * @param courseRound
     * @param beginIndex
     * @param maxResult
     * @return
     */
    @Limit
    @Query("FROM PlannedSchedule WHERE disabled=false AND content IS NOT NULL AND batch.disabled=false AND batch.courseRound=:courseRound ORDER BY batch.sorting ASC,day ASC")
    public List<PlannedSchedule> listPlannedSchedule(@Variable("courseRound") CourseRound courseRound, @Variable("beginIndex") int beginIndex, @Variable("maxResult") int maxResult);

    /**
     * 
     * @param courseSchedule
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND courseSchedule = :courseSchedule ORDER BY id ASC")
    public List<Courseware> listCoursewre(@Variable("courseSchedule") CourseSchedule courseSchedule);

    /**
     * 
     * @param courseSchedule
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND groupAmount != 0 AND movementNumber != 0 AND courseSchedule = :courseSchedule ORDER BY id ASC")
    public List<Courseware> listGeneratedCoursewre(@Variable("courseSchedule") CourseSchedule courseSchedule);

    /**
     * 
     * @param courseRound
     * @param type
     * @param editStatus
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND editStatus = :editStatus")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("editStatus") CoursewareEditStatus editStatus);

    /**
     * 
     * @param courseRound
     * @param type
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type ORDER BY sorting ASC")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type);

    /**
     * 
     * @param ids
     * @return
     */
    @Query("FROM CoursewareTag WHERE disabled = false AND id in (:ids)")
    public List<CoursewareTag> listCoursewareTag(@Variable("ids") List<Long> ids);

    /**
     * 
     * @param dailyCourseware
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND daily = :daily AND type = :type")
    public List<Courseware> listCourseware(@Variable("daily") DailyCourseware dailyCourseware, @Variable("type") CoursewareMovementType type);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM Goal WHERE disabled = false AND courseRound = :courseRound")
    public Goal loadGoal(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BodyDataTarget WHERE disabled = false AND courseRound = :courseRound")
    public List<BodyDataTarget> listBodyDataTarget(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM StudentAssessment WHERE disabled = false AND courseRound = :courseRound ORDER BY createTime DESC")
    public List<StudentAssessment> listStudentAssessment(@Variable("courseRound") CourseRound courseRound);

    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM StudentAssessment WHERE disabled = false AND courseRound = :courseRound ORDER BY createTime DESC")
    public StudentAssessment loadStudentAssessment(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BasicData WHERE disabled = false AND courseRound = :courseRound")
    public BasicData loadBasicData(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM StudentHabit WHERE disabled = false AND courseRound = :courseRound")
    public StudentHabit loadStudentHabit(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM PostureJoint WHERE disabled = false AND courseRound = :courseRound")
    public PostureJoint loadPostureJoint(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM Dietary WHERE disabled = false AND batch = :batch")
    public Dietary loadDietary(@Variable("batch") BatchCourseware batch);

    /**
     * 
     * @param courseRound
     * @param week
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND sorting = :week")
    public BatchCourseware loadBatchCourseare(@Variable("courseRound") CourseRound courseRound, @Variable("week") int week);

    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM Exercise WHERE disabled = false AND batch = :batch")
    public Exercise loadExercise(@Variable("batch") BatchCourseware batch);

    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM PlannedSchedule WHERE disabled = false AND batch = :batch")
    public List<PlannedSchedule> listPlannedSchedule(@Variable("batch") BatchCourseware batch);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM ResultReport WHERE disabled = false AND courseRound = :courseRound")
    public ResultReport loadResultReport(@Variable("courseRound") CourseRound courseRound);

    /**
     * 年卡-课程课件
     * @param courseRound
     * @param type
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type")
    public BatchCourseware loadBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type);

    /**
     * 
     * @param daily
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND daily = :daily")
    public List<Courseware> listCourseware(@Variable("daily") DailyCourseware daily);

    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("SELECT COUNT(*) FROM PlannedSchedule WHERE disabled = false AND batch.courseRound = :courseRound AND batch.sorting < :sorting AND content IS NOT NULL")
    public int countPlannedSchedule(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("SELECT courseware.courseSchedule FROM Courseware courseware"
            + " WHERE courseware.disabled = false AND courseware.groupAmount != 0 AND courseware.movementNumber != 0 AND courseware.courseSchedule.disabled = false"
            + " AND courseware.courseSchedule.occurDate IS NOT NULL AND courseware.courseSchedule.occurHour IS NOT NULL"
            + " AND courseware.courseSchedule.courseRound = :courseRound"
            + " ORDER BY courseware.courseSchedule.occurDate DESC,courseware.courseSchedule.occurHour DESC")
    public CourseSchedule getLatestCourseCourseware(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param courseRound
     * @param editStatus
     * @param type
     * @return
     */
    @Query("SELECT MAX(courseware.daily.sorting) FROM Courseware courseware WHERE courseware.disabled = false AND courseware.daily.disabled = false"
            + " AND courseware.daily.editStatus = :editStatus AND courseware.daily.batch.courseRound = :courseRound AND courseware.daily.batch.type = :type")
    public Integer getMaxSortingOfCourseCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("editStatus") CoursewareEditStatus editStatus, @Variable("type") BatchCoursewareType type);

    /**
     * 
     * @param courseRound
     * @param editStatus
     * @param type
     * @return
     */
    @Query("SELECT MAX(batch.sorting) FROM BatchCourseware batch WHERE batch.disabled = false AND batch.type = :type AND batch.editStatus = :editStatus AND batch.courseRound = :courseRound")
    public Integer getMaxSortingOfWeeklyPlan(@Variable("courseRound") CourseRound courseRound, @Variable("editStatus") CoursewareEditStatus editStatus, @Variable("type") BatchCoursewareType type);

    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND editStatus != 2")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound);

    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND editStatus != 2")
    public List<DailyCourseware> listDailyCourseware(@Variable("batch") BatchCourseware batch);

    /**
     * 
     * @param dailyCourseware
     */
    @Execute("UPDATE Courseware SET disabled = true WHERE disabled = false AND daily = :daily") 
    public void deleteCourseware(@Variable("daily") DailyCourseware dailyCourseware);

    /**
     * 
     * @param batchs
     * @return
     */
    @Execute("UPDATE Dietary SET disabled = true WHERE batch IN (:batchs)")
    public void disableDietary(@Variable("batchs") List<BatchCourseware> batchs);

    /**
     * 
     * @param courseSchedule
     * @param coursewareIds
     */
    @Execute("UPDATE Courseware SET disabled = true WHERE courseSchedule = :courseSchedule AND id IN (:coursewareIds)")
    public void disable(@Variable("courseSchedule") CourseSchedule courseSchedule, @Variable("coursewareIds") List<Long> coursewareIds);

    /**
     * 
     * @param courseRound
     * @param sorting
     */
    @Execute("UPDATE BatchCourseware SET disabled = true WHERE courseRound = :courseRound AND sorting > :sorting")
    public void disableBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("FROM Dietary dietary WHERE dietary.disabled = false AND dietary.batch.courseRound = :courseRound AND dietary.batch.sorting > :sorting")
    public List<Dietary> listDieatry(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("FROM Exercise exercise WHERE exercise.disabled = false AND exercise.batch.courseRound = :courseRound AND exercise.batch.sorting > :sorting")
    public List<Exercise> listExercise(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param type
     * @param maxSorting
     * @param editStatus
     * @return
     */
    @Query("SELECT COUNT(DISTINCT sorting) FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND sorting <= :maxSorting AND editStatus = :editStatus")
    public int countBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("maxSorting") int maxSorting, @Variable("editStatus") CoursewareEditStatus editStatus);

    /**
     * 有上课课件且上课时间最大的课时
     * @param courseRound
     * @return
     */
    @Query("SELECT courseware.courseSchedule FROM Courseware courseware WHERE courseware.disabled = false AND courseware.groupAmount != 0 AND courseware.movementNumber != 0 AND courseware.courseSchedule.disabled = false AND courseware.courseSchedule.occurDate IS NOT NULL AND courseware.courseSchedule.occurHour IS NOT NULL AND courseware.courseSchedule.courseRound = :courseRound ORDER BY courseware.courseSchedule.occurDate DESC, courseware.courseSchedule.occurHour DESC")
    public CourseSchedule loadCourseSchedue(@Variable("courseRound") CourseRound courseRound);
}
